#!/usr/bin/env python
# -*- coding: utf8 -*-

import os
import psutil
import configparser
import time
import sched
import logging


class ProGuard:
    def __init__(self):
        self.nohup = False
        self.proName = ""
        self.proPath = ""

    def initApp(self, cfgfile):
        logging.basicConfig(
            level=logging.DEBUG,
            format=
            '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s ',
            datefmt='%Y-%m-%d %H:%M:%S',
            filename='guard.log',
            filemode='w')
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        formatter = logging.Formatter(
            '%(asctime)s %(name)-12s %(levelname)-5s : %(message)s')
        console.setFormatter(formatter)
        logging.getLogger('').addHandler(console)

        config = configparser.ConfigParser()
        config.read(cfgfile)
        self.nohup = config.getint("app", "nohup")
        self.proName = config.get("app", "proName")
        self.proPath = config.get("app", "proPath")
        if os.name == 'nt':
            self.nohup = False
            if not self.proName.endswith(".exe"):
                self.proName += ".exe"
        if (self.proName == "" or self.proPath == ""):
            return False
        appFile = os.path.join(self.proPath, self.proName)
        if not os.path.exists(appFile):
            logging.error("app path is not exist:%s" % appFile)
            return False
        return True

    def doWork(self, schedule, times):
        schedule.enter(times, 0, self.doWork, (schedule, times))
        logging.info("doWork loop:" +
                     time.strftime("%Y%m%d", time.localtime(time.time())))
        if self.isExitProcess():
            return
        self.startProcess()

    def isExitProcess(self):
        for p in psutil.process_iter():
            try:
                if self.isProcessName(p, self.proName):
                    return True
            except psutil.AccessDenied:
                continue
        return False

    def startProcess(self):
        if self.isExitProcess():
            logging.warn("startProcess failed. process is already run.")
            return
        # now the system is clear, start server processes ...
        nohupArgs = ['nohup'] if self.nohup else []
        appFile = os.path.join(self.proPath, self.proName)
        appProc = psutil.Popen(nohupArgs + [appFile])
        logging.info("startProcess " + appFile + ",result:" + appProc.status())

    def isProcessName(self, p, name):
        try:
            if (p.name() == name or name in p.name()) and name != "":
                return True
            else:
                return False
        except psutil.Error:
            return False


def main():
    guard = ProGuard()
    guard.initApp("guard.ini")
    # second
    times = 60*10
    schedule = sched.scheduler(time.time, time.sleep)
    schedule.enter(times, 0, guard.doWork, (schedule, times))
    schedule.run()


if __name__ == '__main__':
    main()
